/**
 * 
 * @Project HRL Simulation
 * @Date 20.06.2011
 * @Author Aebi Pascal, Kocher Marc, Sriranjan George
 * @School BFH-TI Biel, Projekt 1
 *
 */

package elements;

import utils.Agenda;
import utils.AgendaEntry;


public class Load implements Comparable<Load>{
	
	private String name;
	private String classOfGoods;
	private Agenda agenda;
	private int entryTime;
	private STATE state;
	
	/**
	 * The state of a load defines the current progress to be done with this load.
	 * <ul>
	 * <li> <b>IN</b>, load is ready to schedule the way and time into the rack. If the progress is
	 * finished, the state will be changed to STORE, except the same load will be used to remove
	 * from system, then it gets the state OUT.
	 * <li> <b>OUT</b>, load is ready to move out of the system. After schedule progress state will be changed to 
	 * EXIT. 
	 * <li> <b>STORE</b>, this state is used for an existing system. All loads which begins with this state will be existing 
	 * in the racks, since time=0 of system.
	 * <li> <b>EXIT</b>, this state should never be initialized by the user. The EXIT state will be set after the OUT progress, 
	 * for releasing the load from the system. 
	 * <ul>
	 */
	public enum STATE{IN, OUT, STORE, EXIT}
	
	
	/**
	 * creates a new load with the given parameters.
	 * @param name name/id of load
	 * @param classOfGoods class of goods
	 * @param state see enumeration STATE
	 * @param entryTime time to start schedule
	 */
	public Load(String name, String classOfGoods, STATE state, int entryTime){
		this.name = name;
		this.classOfGoods = classOfGoods;
		this.entryTime = entryTime;
		this.state = state;
		this.agenda = new Agenda();
	}
	
	
	/**
	 * get the agenda of the load
	 * @return agenda of load
	 */
	public Agenda getAgenda() {
		return this.agenda;
	}

	
	/**
	 * get the entry time of the load
	 * @return entry time
	 */
	public int getEntryTime(){
		return this.entryTime;
	}
	
	
	/**
	 * get the class of the load
	 * @return class of the load
	 */
	public String getClassOfGoods(){
		return this.classOfGoods;
	}
	
	
	/**
	 * set the state of the load
	 * @param state
	 */
	public void setState(STATE state) {
		this.state = state;
	}

	
	/**
	 * get the state of the load
	 * @return state
	 */
	public STATE getState() {
		return state;
	}
	
	
	/**
	 * get the name of the load
	 * @return name 
	 */
	public String getName() {
		return name;
	}

	
	/**
	 * set the entry time of the load
	 * @param entryTime
	 */
	public void setEntryTime(int entryTime) {
		this.entryTime = entryTime;
	}

	
	/**
	 * This is a special case if we want to do the OUT progress.
	 * in case we have already scheduled the IN or STORE progress, we get an entry with end time= infinity.
	 * Thus we have to release this entry in the agenda of the load.
	 * This method wont modify the entry, rather delete it.
	 * You have to get sure the modified agenda entry will be added after this method call.
	 * @param time to release the load 
	 */
	public void releaseLoad(int time) {
		AgendaEntry lastAE= this.agenda.getLastEntry();
		this.agenda.removeEntry(lastAE);
	}
	
	
	@Override
	public String toString(){
		if(this.classOfGoods.isEmpty()){
			return "name: " + this.name +"  state: " + this.state + "  time: " + this.entryTime;
		}else{
			return "name: " + this.name + "  class: " + this.classOfGoods + "  state: " + this.state + "  time: " + this.entryTime;
		}
	}


	@Override
	public boolean equals(Object obj) {
		if(!(obj instanceof Load)){
			return false;
		}
		String name = ((Load)obj).getName();
		if(this.name.equals(name)){
			return true;
		}else{
			return false;
		}
	}


	@Override
	public int compareTo(Load load) {
		if(this.entryTime < load.getEntryTime()){
			return -1;
		}
		else if(this.entryTime == load.getEntryTime()){
			return 0;
		}
		else{
			return 1;
		}
	}
	
}
